﻿using MQTT.Chat.Common;
using MQTT.Chat.Model;
using MQTT.Common.Helpers;
using MQTT.Model;
using MQTT.Model.Servers;
using MQTTnet;
using MQTTnet.Client.Options;
using MQTTnet.Extensions.ManagedClient;
using System;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace MQTT.Chat.ViewModel
{
    public class MainViewModel
    {
        public LoginModel LoginModel { get; set; } = new LoginModel();
        public CommandBase ClosWindowCommand { get; set; }
        public CommandBase LoginCommand { get; set; }
        public CommandBase RegisterCommand { get; set; }

        UserEntityService userEntityService = new UserEntityService();
        private IManagedMqttClient mqttClient;
        public MainViewModel()
        {
            #region MQTT
            // 初始化Client
            mqttClient = new MqttFactory().CreateManagedMqttClient();

            mqttClient.UseDisconnectedHandler(ee =>
            {
                WriteLog(">>> 服务器断开连接");
            });
            mqttClient.UseApplicationMessageReceivedHandler(ee =>
            {
                WriteLog(">>> 收到消息");
                WriteLog($"+ Topic = {ee.ApplicationMessage.Topic}");
                try
                {
                    WriteLog($"+ Payload = {Encoding.UTF8.GetString(ee.ApplicationMessage.Payload)}");
                }
                catch { }
                WriteLog($"+ QoS = {ee.ApplicationMessage.QualityOfServiceLevel}");
                WriteLog($"+ Retain = {ee.ApplicationMessage.Retain}");
                WriteLog("");
            });

            mqttClient.UseConnectedHandler(ee =>
            {
                WriteLog(">>> 连接到服务");
            });
            #endregion

            #region 关闭窗口命令
            ClosWindowCommand = new CommandBase();
            ClosWindowCommand.DoExecute = new Action<object>((o) =>
            {
                (o as Window).Close();
            });
            ClosWindowCommand.DoCanExecute = new Func<object, bool>((o) => { return true; });
            #endregion

            #region 登录命令
            LoginCommand = new CommandBase();
            LoginCommand.DoExecute = new Action<object>(DoLogin);
            LoginCommand.DoCanExecute = new Func<object, bool>((o) => { return true; });
            #endregion

            #region 注册命令
            RegisterCommand = new CommandBase();
            RegisterCommand.DoExecute = new Action<object>(DoRegister);
            RegisterCommand.DoCanExecute = new Func<object, bool>((o) => { return true; });
            #endregion

        }

        private void DoLogin(object o)
        {
            Task.Run(async () =>
            {
                if (string.IsNullOrEmpty(LoginModel.UserName))
                {
                    MessageBox.Show("请输入用户名");
                    return;
                }

                if (string.IsNullOrEmpty(LoginModel.Password))
                {
                    MessageBox.Show("请输入密码");
                    return;
                }

                var user = await userEntityService.Get(x => x.Account == LoginModel.UserName);
                if (user == null)
                {
                    MessageBox.Show("账号或密码错误");
                    return;
                }

                if (user.Password != MD5Encrypt.Encrypt64($"{LoginModel.Password}@{LoginModel.UserName}"))
                {
                    MessageBox.Show("账号或密码错误");
                    return;
                }

                // 向服务端开放的端口进行服务请求
                var mqttClientOptions = new MqttClientOptionsBuilder()
                                 .WithClientId(LoginModel.UserName)// 传入ClientID参数
                                 .WithTcpServer("127.0.0.1", 1883)//指定TCP连接的IP和Port
                                 .WithCleanSession(false)//false 接收离线消息 服务端需要启用之久会话 WithPersistentSessions
                                 .WithWillMessage(new MqttApplicationMessage { Topic = "ooo", Payload = Encoding.UTF8.GetBytes("下线通知"), Retain = true })
                                 .WithWillDelayInterval(1)
                                 .WithCredentials("admin", "123456");//指定连接的用户名和密码

                var options = new ManagedMqttClientOptionsBuilder()
                            .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
                            .WithClientOptions(mqttClientOptions.Build())
                            .Build();

                await mqttClient.StartAsync(options);
                MessageBox.Show($"登录成功");
            });
        }

        private void DoRegister(object o)
        {
            Task.Run(async () =>
            {
                if (string.IsNullOrEmpty(LoginModel.UserName))
                {
                    MessageBox.Show("请输入用户名");
                    return;
                }

                if (string.IsNullOrEmpty(LoginModel.Password))
                {
                    MessageBox.Show("请输入密码");
                    return;
                }

                bool exist = await userEntityService.ExistAsync(x => x.Account == LoginModel.UserName);
                if (exist)
                    MessageBox.Show($"{LoginModel.UserName}账号已存在");

                await userEntityService.CreateAsync(new UserEntity
                {
                    Account = LoginModel.UserName,
                    Password = MD5Encrypt.Encrypt64($"{LoginModel.Password}@{LoginModel.UserName}")
                });
                MessageBox.Show($"注册成功");
            });
        }

        public void WriteLog(string message)
        {
            //if (!(txtRich.CheckAccess()))
            //{
            //    this.Dispatcher.Invoke(() => WriteLog(message));
            //    return;
            //}
            //string strTime = "[" + System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "] ";
            //txtRich.AppendText(strTime + message + "\r");
        }
    }
}
